﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Data;

using OpenChart.Entities;
using OpenChart.PublicUnits;
using OpenChart.Check;

namespace OpenChart.DrawChart
{
    /// <summary>
    /// 用于绘制图形的类
    /// </summary>
    internal abstract class AbsDrawingChart
    {
        private int _axisXIndex = 1;//用于记录当前绘制的横坐标
        private int _xScaleCount;//X轴格数
        private int _yScaleCount;//Y轴格数

        /// <summary>
        /// 坐标距离画布左边界距离
        /// </summary>
        protected const int CON_LEFT_RANGE = 100;

        /// <summary>
        /// 坐标距离画布右边界距离
        /// </summary>
        protected const int CON_RIGTH_RANGE = 180;

        /// <summary>
        /// 坐标距离画布上边界距离
        /// </summary>
        protected const int CON_UP_RANGE = 60;

        /// <summary>
        /// 坐标距离画布下边界距离
        /// </summary>
        protected const int CON_DOWN_RANGE = 120;

        /// <summary>
        /// X坐标所能表示的最大值
        /// </summary>
        protected double _maxXValue;

        /// <summary>
        /// Y轴所所能表示的最大值
        /// </summary>
        protected double _maxYValue;

        /// <summary>
        /// X轴所能表示的最小值
        /// </summary>
        protected double _minXValue;

        /// <summary>
        /// Y轴所能表示的最小值
        /// </summary>
        protected double _minYValue;

        #region 公共（及受保护的）属性、方法

        /// <summary>
        /// 要绘制的ChartArea
        /// </summary>
        public ChartArea ChartArea { get; set; }

        /// <summary>
        /// GDI+ 绘图图面
        /// </summary>
        public Graphics Graphics { get; set; }

        /// <summary>
        /// 画布宽度
        /// </summary>
        public float CanvasWidth { get; set; }

        /// <summary>
        /// 画布高度
        /// </summary>
        public float CanvasHeight { get; set; }

        /// <summary>
        /// 绘制图形
        /// </summary>
        public void DrawChart()
        {
            this.DoOnce();
            this.DrawAxis();
            this.DrawAxisLable();
            this.DrawChartAreaTitle();
            this.DrawXSacle();
            this.DrawYScale();
            this.DrawData();
            this.DrawLegends();
            this.DrawPartingLines();
        }

        /// <summary>
        /// 初始化操作(仅执行一次的操作放在这里)
        /// </summary>
        protected virtual void Init()
        {
            CalculateMaxMinValue();//计算坐标轴所能表示的最大值和最小值
            this.SetSeriesColor();//设置Series的颜色
        }

        /// <summary>
        /// 绘制分割线
        /// </summary>
        protected virtual void DrawPartingLines()
        {
            foreach (var item in this.ChartArea.PartingLines)
            {
                this.DrawPartingLine(item);
            }
        }

        /// <summary>
        /// 绘制坐标轴Lable
        /// </summary>
        protected virtual void DrawAxisLable()
        {
            string fontFamilyName;
            Color lableColor;
            int size;
            string strValue;
            RectangleF rect;
            Brush brush;
            StringFormat format = new StringFormat();
            //
            //绘制横坐标Lable
            //
            if (this.ChartArea.AxisX.Lable.Value != null && this.ChartArea.AxisX.Lable.Value != string.Empty)
            {
                fontFamilyName = this.ChartArea.AxisX.Lable.FontFamilyName;
                lableColor = this.ChartArea.AxisX.Lable.Color;
                size = this.ChartArea.AxisX.Lable.Size;
                strValue = this.ChartArea.AxisX.Lable.Value;

                rect = new RectangleF(10, this.CanvasHeight - CON_DOWN_RANGE / 2 - this.ChartArea.AxisY1.Lable.Size - 10, CON_LEFT_RANGE - 10, this.CanvasWidth);
                brush = new SolidBrush(lableColor);
                format.Alignment = StringAlignment.Near;
                this.Graphics.DrawString("X:" + strValue, new Font(fontFamilyName, size), brush, rect, format);
            }
            //
            //绘制纵坐标Lable
            //
            if (this.ChartArea.AxisY1.Lable.Value != null && this.ChartArea.AxisY1.Lable.Value != string.Empty)
            {
                fontFamilyName = this.ChartArea.AxisY1.Lable.FontFamilyName;
                lableColor = this.ChartArea.AxisY1.Lable.Color;
                size = this.ChartArea.AxisY1.Lable.Size;
                strValue = this.ChartArea.AxisY1.Lable.Value;

                rect = new RectangleF(10, this.CanvasHeight - CON_DOWN_RANGE / 2, CON_LEFT_RANGE - 10, this.CanvasWidth);
                brush = new SolidBrush(lableColor);
                this.Graphics.DrawString("Y:" + strValue, new Font(fontFamilyName, size), brush, rect, format);
            }
        }

        /// <summary>
        /// 绘制数据
        /// </summary>
        protected abstract void DrawData();

        /// <summary>
        /// 绘制图例
        /// </summary>
        protected virtual void DrawLegends()
        {
            int yPosition = CON_UP_RANGE;
            foreach (var item in this.ChartArea.Series)
            {
                this.DrawOneLegend(item, yPosition);
                yPosition += 15;
            }
        }

        /// <summary>
        /// 绘制坐标
        /// </summary>
        protected virtual void DrawAxis()
        {
            int arraowRatio = 4;//箭头大小与线宽度的比例
            Pen pen = new Pen(this.ChartArea.AxisLineColor);
            pen.Width = this.ChartArea.AxisLineWidth;
            //
            //坐标
            //
            PointF xStart = new PointF(CON_LEFT_RANGE, this.CanvasHeight - CON_DOWN_RANGE);
            PointF xEnd = new PointF(this.CanvasWidth - CON_RIGTH_RANGE + this.ChartArea.AxisLineWidth * arraowRatio * 2, this.CanvasHeight - CON_DOWN_RANGE);//给箭头预留this.ChartArea.AxisLineWidth * arraowRatio * 2
            PointF yStart = xStart;
            PointF yEnd = new PointF(CON_LEFT_RANGE, CON_UP_RANGE - this.ChartArea.AxisLineWidth * arraowRatio * 2);//给箭头预留this.ChartArea.AxisLineWidth * arraowRatio * 2


            this.Graphics.DrawLine(pen, xStart, xEnd);
            this.Graphics.DrawLine(pen, yStart, yEnd);
            //
            //箭头
            //
            PointF[] pointsX = new PointF[3];
            pointsX[0] = xEnd;
            pointsX[1] = new PointF(xEnd.X - this.ChartArea.AxisLineWidth * arraowRatio, xEnd.Y - this.ChartArea.AxisLineWidth * arraowRatio);
            pointsX[2] = new PointF(xEnd.X - this.ChartArea.AxisLineWidth * arraowRatio, xEnd.Y + this.ChartArea.AxisLineWidth * arraowRatio);

            PointF[] pointsY = new PointF[3];
            pointsY[0] = yEnd;
            pointsY[1] = new PointF(yEnd.X - this.ChartArea.AxisLineWidth * arraowRatio, yEnd.Y + this.ChartArea.AxisLineWidth * arraowRatio);
            pointsY[2] = new PointF(yEnd.X + this.ChartArea.AxisLineWidth * arraowRatio, yEnd.Y + this.ChartArea.AxisLineWidth * arraowRatio);

            this.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            Brush brush = new SolidBrush(this.ChartArea.AxisLineColor);
            GraphicsPath pathX = new GraphicsPath();
            pathX.AddLines(pointsX);

            GraphicsPath pathY = new GraphicsPath();
            pathY.AddLines(pointsY);

            this.Graphics.FillPath(brush, pathX);
            this.Graphics.FillPath(brush, pathY);

            this.Graphics.SmoothingMode = SmoothingMode.Default;
        }

        /// <summary>
        /// 绘制坐标刻度及网格
        /// </summary>
        protected virtual void DrawXSacle()
        {
            _axisXIndex = 1;

            double interval = ChartHelper.GetInterval(this.ChartArea.AxisX.Interval.Value, this.ChartArea.AxisX.IntervalType);
            float axisWidth = this.CanvasWidth - CON_LEFT_RANGE - CON_RIGTH_RANGE;
            float scaleWidth = axisWidth / _xScaleCount;
            float lableWidth = this.GetXSacleWidth();
            double lableValue = _minXValue;
            for (int i = 0; i <= _xScaleCount; i++)
            {
                this.DarwOneXScaleAndLable(scaleWidth, lableValue, lableWidth);
                lableValue += interval;
            }
        }

        /// <summary>
        /// 绘制坐标刻度及网格
        /// </summary>
        protected virtual void DrawYScale()
        {
            double interval = ChartHelper.GetInterval(this.ChartArea.AxisY1.Interval.Value, this.ChartArea.AxisY1.IntervalType);
            float axisWidth = this.CanvasHeight - CON_UP_RANGE - CON_DOWN_RANGE;
            float scaleWidth = axisWidth / _yScaleCount;

            double lableValue = _minYValue;
            for (int i = 0; i <= _yScaleCount; i++)
            {
                this.DarwOneYScaleAndLable(scaleWidth, lableValue);
                lableValue += interval;
            }
        }

        #endregion

        #region 绘制刻度及网格（这些私有方法仅适用于大部分图形的绘制，如果变化，则在子类里重写该类中的protected方法）

        #region X轴相关

        //绘制一个X轴刻度及刻度值。width:两个相邻坐标点之间的距离，lableValue：坐标显示值;lableWidth:坐标值长度
        private void DarwOneXScaleAndLable(float width, double lableValue, float lableWidth)
        {
            string lable = ChartHelper.GetAxisLable(lableValue, this.ChartArea.AxisX.IntervalType, this.ChartArea.AxisX.TimeFormat);
            float position = this.GetXPixelPositionByValue(lableValue);
            DrawOneXScale(lableValue, position);//绘制一个刻度
            DrawOneXScaleLable(width, lableWidth, lable, position);//绘制一个刻度值
        }

        //绘制一个X坐标刻度值
        private void DrawOneXScaleLable(float width, float lableWidth, string lable, float position)
        {
            RectangleF rect = new RectangleF();
            StringFormat stringformat = null;
            //
            //如果绘制区域大于绘制内容的长度
            //
            if (width >= lableWidth)
            {
                rect.Location = new PointF(position - width / 2, this.CanvasHeight - CON_DOWN_RANGE + 5);
                rect.Size = new SizeF(width, 15);
                stringformat = new StringFormat();
                stringformat.Alignment = StringAlignment.Center;
            }
            //
            //如果绘制区域小于绘制内容长度且大于绘制长度1/2
            //
            else if (width <= lableWidth && width > lableWidth / 2)
            {
                if (_axisXIndex % 2 == 0)
                {
                    rect.Location = new PointF(position - width, this.CanvasHeight - CON_DOWN_RANGE + 5 + 15);
                }
                else
                {
                    rect.Location = new PointF(position - width, this.CanvasHeight - CON_DOWN_RANGE + 5);
                }
                rect.Size = new SizeF(width * 2, 15);
                stringformat = new StringFormat();
                stringformat.Alignment = StringAlignment.Center;
                _axisXIndex++;
            }
            //
            //如果绘制区域小于绘制内容长度的1/2
            else if (width <= lableWidth / 2)
            {
                rect.Location = new PointF(position - 15 / 2, this.CanvasHeight - CON_DOWN_RANGE + 5);
                rect.Size = new SizeF(15, CON_DOWN_RANGE - 5);
                stringformat = new StringFormat(StringFormatFlags.DirectionVertical);
                stringformat.LineAlignment = StringAlignment.Center;
                stringformat.Alignment = StringAlignment.Near;
            }
            Brush brush = new SolidBrush(this.ChartArea.AxisLineColor);
            double number = 0d;
            if (double.TryParse(lable, out number))
            {
                if (number > 9999)
                {
                    lable = number.ToString("e2");
                }
            }
            this.Graphics.DrawString(lable, new Font("宋体", 12), brush, rect, stringformat);
        }

        //绘制一个X坐标刻度和网格
        private void DrawOneXScale(double lableValue, float position)
        {
            if (this.ChartArea.AxisX.ShowGrid)
            {
                if (lableValue != _minXValue)//第一个坐标无需绘制网格
                {
                    Pen pen = new Pen(this.ChartArea.AxisX.Grid.LineColor, this.ChartArea.AxisX.Grid.LineWidth);
                    DashStyle style = ChartHelper.GetDashStyle(this.ChartArea.AxisX.Grid.LineStyle);
                    pen.DashStyle = style;
                    this.Graphics.DrawLine(pen, position, CON_UP_RANGE, position, this.CanvasHeight - CON_DOWN_RANGE);
                }
            }
            else//绘制刻度
            {
                Pen pen = new Pen(this.ChartArea.AxisLineColor);
                this.Graphics.DrawLine(pen, position, this.CanvasHeight - CON_DOWN_RANGE, position, this.CanvasHeight - CON_DOWN_RANGE - 10);
            }
        }

        //获得X轴刻度lable的长度
        private float GetXSacleWidth()
        {
            double interval = ChartHelper.GetInterval(this.ChartArea.AxisX.Interval.Value, this.ChartArea.AxisX.IntervalType);
            double lableValue = _minXValue;
            if (this.ChartArea.AxisX.IntervalType == Enums.InervalType.Number)
            {
                string label = ChartHelper.GetAxisLable(lableValue, this.ChartArea.AxisX.IntervalType, this.ChartArea.AxisX.TimeFormat);
                float width = this.Graphics.MeasureString(label, new Font("宋体", 12)).Width;
                for (int i = 1; i <= _xScaleCount; i++)
                {
                    lableValue += interval;
                    label = ChartHelper.GetAxisLable(lableValue, this.ChartArea.AxisX.IntervalType, this.ChartArea.AxisX.TimeFormat);
                    float tempWidth = this.Graphics.MeasureString(label, new Font("宋体", 12)).Width;
                    if (tempWidth > width)
                    {
                        width = tempWidth;
                    }
                }
                return width;
            }
            else
            {
                string label = ChartHelper.GetAxisLable(lableValue, this.ChartArea.AxisX.IntervalType, this.ChartArea.AxisX.TimeFormat);
                return this.Graphics.MeasureString(label, new Font("宋体", 12)).Width;
            }
        }

        #endregion

        #region Y轴相关

        //绘制一个Y轴刻度及刻度值。width：两个相邻坐标点之间的距离,lableValue:坐标显示值
        private void DarwOneYScaleAndLable(float width, double lableValue)
        {
            string lable = ChartHelper.GetAxisLable(lableValue, this.ChartArea.AxisY1.IntervalType, this.ChartArea.AxisY1.TimeFormat);
            float position = this.GetYPixelPositionByValue(lableValue);
            DrawOneYScale(lableValue, position);//绘制一个Y轴刻度和网格
            DrawOneYScaleLable(width, lable, position);//绘制一个Y轴刻度值
        }

        //绘制一个Y轴刻度值
        private string DrawOneYScaleLable(float width, string lable, float position)
        {
            RectangleF rect = new RectangleF(5, position - width / 2, CON_LEFT_RANGE - 5, width);
            StringFormat stringFormat = new StringFormat();
            stringFormat.Alignment = StringAlignment.Far;
            stringFormat.LineAlignment = StringAlignment.Center;
            Brush brush = new SolidBrush(this.ChartArea.AxisLineColor);

            double number = 0d;
            if (double.TryParse(lable, out number))
            {
                if (number > 9999)
                {
                    lable = number.ToString("e2");
                }
            }

            this.Graphics.DrawString(lable, new Font("宋体", 12), brush, rect, stringFormat);
            return lable;
        }

        //绘制一个Y轴刻度和网格
        private void DrawOneYScale(double lableValue, float position)
        {
            if (this.ChartArea.AxisY1.ShowGrid)
            {
                if (lableValue != _minYValue)//第一个坐标无需绘制网格
                {
                    Pen pen = new Pen(this.ChartArea.AxisY1.Grid.LineColor);
                    pen.DashStyle = ChartHelper.GetDashStyle(this.ChartArea.AxisY1.Grid.LineStyle);
                    this.Graphics.DrawLine(pen, CON_LEFT_RANGE, position, this.CanvasWidth - CON_RIGTH_RANGE, position);
                }
            }
            else
            {
                Pen pen = new Pen(this.ChartArea.AxisLineColor);
                this.Graphics.DrawLine(pen, CON_LEFT_RANGE, position, CON_LEFT_RANGE + 10, position);
            }
        }

        //从DataTable获得Y轴最大值
        private double GetMaxYValueFromData()
        {
            double maxValue = double.MinValue;
            double maxValueOfDt = 0d;
            foreach (var item in this.ChartArea.Series)
            {
                if (this.ChartArea.AxisY1.IntervalType == Enums.InervalType.Number)
                {
                    maxValueOfDt = Convert.ToDouble(this.ChartArea.Data.GetMaxValue(item.YValueMember));
                }
                else
                {
                    maxValueOfDt = Convert.ToDateTime(this.ChartArea.Data.GetMaxValue(item.YValueMember)).ToOADate();
                }
                if (Convert.ToDouble(maxValueOfDt) > maxValue)
                {
                    maxValue = Convert.ToDouble(maxValueOfDt);
                }
            }
            return maxValue;
        }

        //从DateTable获得Y轴最小值
        private double GetMinYValueFromData()
        {
            double minValue = double.MaxValue;
            double minValueOfDt = 0d;
            foreach (var item in this.ChartArea.Series)
            {
                if (this.ChartArea.AxisY1.IntervalType == Enums.InervalType.Number)
                {
                    minValueOfDt = Convert.ToDouble(this.ChartArea.Data.GetMinValue(item.YValueMember));
                }
                else
                {
                    minValueOfDt = Convert.ToDateTime(this.ChartArea.Data.GetMinValue(item.YValueMember)).ToOADate();
                }
                if (Convert.ToDouble(minValueOfDt) < minValue)
                {
                    minValue = Convert.ToDouble(minValueOfDt);
                }
            }
            return minValue;
        }

        #endregion

        #endregion

        #region 绘制图例（这些私有方法仅适用于大部分图形的绘制，如果变化，则在子类里重写该类中的protected方法）

        //为参数指定的series绘制图例(要绘制的位置纵坐标)
        private void DrawOneLegend(Series series,int yPosition)
        {
            this.Graphics.DrawLine(new Pen(series.Color, 10), this.CanvasWidth - CON_RIGTH_RANGE + 10, yPosition, this.CanvasWidth - CON_RIGTH_RANGE + 10 + 35, yPosition);
            this.Graphics.DrawString(series.Name, new Font("宋体", 12), new SolidBrush(series.Color), this.CanvasWidth - CON_RIGTH_RANGE + 10 + 35 + 10, yPosition - 10);
        }

        #endregion

        #region 绘制分割线（这些私有方法仅适用于大部分图形的绘制，如果变化，则在子类里重写该类中的protected方法）

        //绘制分割线
        private void DrawPartingLine(PartingLine item)
        {
            //
            //绘制横线
            //
            float position = this.GetYPixelPositionByValue(item.YValue);
            Pen pen = new Pen(item.LineColor,item.LineWidth);
            pen.DashStyle = ChartHelper.GetDashStyle(item.LineStyle);
            this.Graphics.DrawLine(pen, CON_LEFT_RANGE, position, this.CanvasWidth - CON_RIGTH_RANGE, position);

            //
            //绘制刻度显示值
            //
            string lable = string.Empty;
            if (item.YValue > 9999)
            {
                lable = item.YValue.ToString("e2");
            }
            else
            {
                lable = item.YValue.ToString();
            }
            RectangleF rect = new RectangleF(5, position - 10, CON_LEFT_RANGE - 5, 20);
            StringFormat stringFormat = new StringFormat();
            stringFormat.Alignment = StringAlignment.Far;
            stringFormat.LineAlignment = StringAlignment.Center;
            Brush brush = new SolidBrush(item.LineColor);
            this.Graphics.DrawString(lable, new Font("宋体", 12), brush, rect, stringFormat);

        }

        //根据Y轴值返回像素位置
        private float GetYPixelPositionByValue(double value)
        {
            float yValuePerPixel = (float)(_maxYValue - _minYValue) / (this.CanvasHeight - CON_DOWN_RANGE - CON_UP_RANGE);
            float drawYPixel = (float)(this.CanvasHeight - CON_DOWN_RANGE - (value - _minYValue) / yValuePerPixel);
            return drawYPixel;
        }

        private float GetXPixelPositionByValue(double value)
        {
            float xValuePerPixel = (float)(_maxXValue - _minXValue) / (this.CanvasWidth - CON_LEFT_RANGE - CON_RIGTH_RANGE);
            float drawXPixel = (float)(CON_LEFT_RANGE + (value - _minXValue) / xValuePerPixel);
            return drawXPixel;
        }

        #endregion

        //检查数据的合法性
        private void CheckAndThrowException()
        {
            AbsChecking check = CheckingFactory.Create(this.ChartArea);
            check.CheckAndThrowException();
        }

        private bool _haveDone;

        //在绘制图形之前进行的操作(仅进行一次)
        private void DoOnce()
        {
            if (_haveDone == false)
            {
                this.CheckAndThrowException();
                this.Init();
                _haveDone = true;
            }
        }

        //绘制ChartArea的显示标题
        private void DrawChartAreaTitle()
        {
            RectangleF rect = new RectangleF(0f, CON_UP_RANGE / 4 * 1, this.CanvasWidth, this.CanvasHeight);//显示标题的区域
            Brush brush = new SolidBrush(this.ChartArea.ChartTitle.Color);
            StringFormat format = new StringFormat();
            format.Alignment = StringAlignment.Center;
            this.Graphics.DrawString(this.ChartArea.ChartTitle.Value, new Font(this.ChartArea.ChartTitle.FontFamilyName, this.ChartArea.ChartTitle.Size, FontStyle.Bold), brush, rect, format);
        }

        ////计算坐标轴所能表示的最大值和最小值
        private void CalculateMaxMinValue()
        {
            double maxXValue, minXValue;
            if (this.ChartArea.AxisX.MinVAlue != null)
            {
                minXValue = this.ChartArea.AxisX.MinVAlue.Value;
            }
            else
            {
                if (this.ChartArea.AxisX.IntervalType == Enums.InervalType.Number)
                {
                    minXValue = Double.Parse(this.ChartArea.Data.Rows[0][this.ChartArea.XValueMember].ToString());
                }
                else
                {
                    minXValue = Convert.ToDateTime(this.ChartArea.Data.Rows[0][this.ChartArea.XValueMember]).ToOADate();
                }
            }
            if (this.ChartArea.AxisX.MaxValue != null)
            {
                maxXValue = this.ChartArea.AxisX.MaxValue.Value;
            }
            else
            {
                if (this.ChartArea.AxisX.IntervalType == Enums.InervalType.Number)
                {
                    maxXValue = Double.Parse(this.ChartArea.Data.Rows[this.ChartArea.Data.Rows.Count - 1][this.ChartArea.XValueMember].ToString());
                }
                else
                {
                    maxXValue = Convert.ToDateTime(this.ChartArea.Data.Rows[this.ChartArea.Data.Rows.Count - 1][this.ChartArea.XValueMember]).ToOADate();
                }
            }
            _minXValue = minXValue;
            _xScaleCount = (int)Math.Ceiling((maxXValue - minXValue) / ChartHelper.GetInterval(this.ChartArea.AxisX.Interval.Value, this.ChartArea.AxisX.IntervalType));
            _maxXValue = _minXValue + ChartHelper.GetInterval(this.ChartArea.AxisX.Interval.Value, this.ChartArea.AxisX.IntervalType) * _xScaleCount;

            double minYValue, maxYValue;
            if (this.ChartArea.AxisY1.MinVAlue != null)
            {
                minYValue = this.ChartArea.AxisY1.MinVAlue.Value;
            }
            else
            {
                minYValue = this.GetMinYValueFromData();
            }

            if (this.ChartArea.AxisY1.MaxValue != null)
            {
                maxYValue = this.ChartArea.AxisY1.MaxValue.Value;
            }
            else
            {
                maxYValue = this.GetMaxYValueFromData();
            }
            _minYValue = minYValue;
            _yScaleCount = (int)Math.Ceiling((maxYValue - minYValue) / ChartHelper.GetInterval(this.ChartArea.AxisY1.Interval.Value, this.ChartArea.AxisY1.IntervalType));
            _maxYValue = _minYValue + ChartHelper.GetInterval(this.ChartArea.AxisY1.Interval.Value, this.ChartArea.AxisY1.IntervalType) * _yScaleCount;
        }

        //为没有设置颜色的series设置Series的颜色
        private void SetSeriesColor()
        {
            foreach (var item in this.ChartArea.Series)
            {
                if (item.Color.IsEmpty)
                {
                    Color color = ChartHelper.GetRandomColor();
                    while (this.HaveColorExists(color))
                    {
                        color = ChartHelper.GetRandomColor();
                    }
                    item.Color = color;
                }
            }
        }

        //颜色是否已经存在
        private bool HaveColorExists(Color color)
        {
            foreach (var item in this.ChartArea.Series)
            {
                if ((!item.Color.IsEmpty) && item.Color == color)
                {
                    return true;
                }
            }
            return false;
        }
    }
}

